/* * ============================================================================ * GNU Lesser General Public License * ============================================================================ * * Beanlet - JSE Application Container. * Copyright (C) 2006 Leon van Zantvoort * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * Leon van Zantvoort * 243 Acalanes Drive #11 * Sunnyvale, CA 94086 * USA * * zantvoort@users.sourceforge.net * http://beanlet.org */ package org.beanlet.transaction.impl; import java.lang.reflect.Member; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; import org.beanlet.BeanletApplicationContext; import org.beanlet.BeanletTypeIsDuplicateException; import org.beanlet.BeanletTypeNotFoundException; import org.jargo.ComponentContext; import org.jargo.ComponentReference; /** * * @author Leon van Zantvoort */ final class TransactionHelper { private static final BeanletApplicationContext ctx = BeanletApplicationContext.instance(); private static final AtomicReference<Set<String>> txdeps = new AtomicReference<Set<String>>(); private static final AtomicReference<Set<String>> utdeps = new AtomicReference<Set<String>>(); private static final AtomicReference<TransactionManager> tx = new AtomicReference<TransactionManager>(); private TransactionHelper() { } public static Set<String> getTransactionManagerDependencies() { Set<String> deps = txdeps.get(); if (deps == null) { deps = ctx.getBeanletNamesForType(TransactionManager.class, true, false); txdeps.set(deps); } return deps; } public static Set<String> getUserTransactionDependencies() { Set<String> deps = utdeps.get(); if (deps == null) { deps = ctx.getBeanletNamesForType(UserTransaction.class, true, false); utdeps.set(deps); } return deps; } public static TransactionManager getTransactionManager(String beanletName, Member member) { TransactionManager t = tx.get(); if (t == null) { Set<String> names = BeanletApplicationContext.instance(). getBeanletNamesForType(TransactionManager.class, true, true); if (names.isEmpty()) { throw new BeanletTypeNotFoundException(beanletName, member, TransactionManager.class); } if (names.size() > 1) { throw new BeanletTypeIsDuplicateException(beanletName, member, TransactionManager.class, names); } t = BeanletApplicationContext.instance().getBeanlet( names.iterator().next(), TransactionManager.class); tx.set(t); } return t; } public static UserTransaction getUserTransaction(ComponentContext<?> ctx, Member member, final TransactionManager tm) { Set<String> names = BeanletApplicationContext.instance(). getBeanletNamesForType(UserTransaction.class, true, true); if (names.isEmpty()) { // This is allowed. return null; // Use the following line instead to enforce the availability of UserTransaction. // throw new BeanletTypeNotFoundException( // ctx.getComponentMetaData().getComponentName(), // getMember(ea.getElement()), UserTransaction.class); } if (names.size() > 1) { throw new BeanletTypeIsDuplicateException(ctx.getComponentMetaData(). getComponentName(), member, UserTransaction.class, names); } final UserTransaction ut = BeanletApplicationContext.instance(). getBeanlet(names.iterator().next(), UserTransaction.class); final ComponentReference<?> reference = ctx.reference().weakReference(); return new UserTransaction() { public void begin() throws NotSupportedException,SystemException { ut.begin(); Transaction tx = tm.getTransaction(); assert tx != null; TransactionLocalDelegateImpl.begin(tx); TransactionLocalDelegateImpl.userTransaction(reference); } public void commit() throws RollbackException,HeuristicMixedException,HeuristicRollbackException,SecurityException,IllegalStateException,SystemException { Transaction tx = tm.getTransaction(); assert tx != null; ut.commit(); TransactionLocalDelegateImpl.commit(tx); } public int getStatus() throws SystemException { return ut.getStatus(); } public void rollback() throws IllegalStateException,SecurityException,SystemException { Transaction tx = tm.getTransaction(); assert tx != null; ut.rollback(); TransactionLocalDelegateImpl.commit(tx); } public void setRollbackOnly() throws IllegalStateException,SystemException { ut.setRollbackOnly(); } public void setTransactionTimeout(int i) throws SystemException { ut.setTransactionTimeout(i); } }; } }